package model;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Random;

public class Cellule implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -9184564010246466620L;
	private int life = 0;
	private Coordonnee coord = null;

	public Cellule(Coordonnee coord) {
		this.coord = new Coordonnee(coord.getHauteur(), coord.getLargeur(),
				coord.getHauteurMax(), coord.getLargeurMax());
		if (Rules.randomLife()) {
			Random rand = new Random();
			this.life = rand.nextInt(Rules.getMaxLife());
		} else {
			this.life = Rules.getMaxLife();
		}
	}

	public int getLife() {
		return life;
	}

	private void ajouteDonneVie(
			HashMap<Coordonnee, Integer> mapDonneVie, Coordonnee coord, int b) {
		mapDonneVie.put(coord, new Integer(b));
	}

	private Integer getDonneVie(
			HashMap<Coordonnee, Integer> mapDonneVie, Coordonnee coord) {
		Integer i = null;
		i = mapDonneVie.get(coord);
		return i;
	}

	synchronized static void ajouteCellule(
			HashMap<Coordonnee, Cellule> mapTps2, Cellule t) {
		mapTps2.put(t.coord, t);
	}

	public void traitement(HashMap<Coordonnee, Cellule> mapTps1,
			HashMap<Coordonnee, Cellule> mapTps2,
			HashMap<Coordonnee, Integer> mapDonneVie, int nbVoisineMax) {
		int hauteur;
		int largeur;
		int largeurMax;
		int hauteurMax;
		hauteur = coord.getHauteur();
		largeur = coord.getLargeur();
		largeurMax = coord.getLargeurMax();
		hauteurMax = coord.getHauteurMax();
		int nbCelluleVoisine = 0;
		for (int j = hauteur - 1; j <= hauteur + 1; j++) {
			for (int i = largeur - 1; i <= largeur + 1; i++) {
				Coordonnee cTmp = new Coordonnee(j, i, hauteurMax,
						largeurMax);
				if (cTmp.isValid()) {
					
					if (Rules.giveLife()) {
						if (i != largeur || j != hauteur) {
							Integer a = getDonneVie(mapDonneVie, cTmp);
							if (a == null)
								a = new Integer(0);
							int b = a.intValue();
							b++;
							if (b <= 8) {
								ajouteDonneVie(mapDonneVie, cTmp, b);
							}
						} else {
							ajouteDonneVie(mapDonneVie, cTmp, nbVoisineMax + 1);
						}
					}
					if (i != largeur || j != hauteur) {
						if (mapTps1.get(cTmp) != null) {
							nbCelluleVoisine++;
						}
					}
				}
			}
		}
		if (nbCelluleVoisine == 2 || nbCelluleVoisine == 3) {
			if (Rules.haveLife()) {
				this.life--;
				if (this.life > 0)
					ajouteCellule(mapTps2, this);
			} else
				ajouteCellule(mapTps2, this);
		} else if (this.life > 0 && Rules.haveLife()) {
			this.life--;
			ajouteCellule(mapTps2, this);
		}
	}

	public static void traitementThread(HashMap<Coordonnee, Cellule> mapTps1,
			HashMap<Coordonnee, Cellule> mapTps2,
			HashMap<Coordonnee, Integer> mapDonneVie, int nbVoisine, int x,
			int largeurMax, int hauteurMax) {
		int nbCelluleVoisine = 0;
		int nbVoisin = 0;
		Coordonnee coord = new Coordonnee(x, hauteurMax, largeurMax);
		int largeur = x % largeurMax;
		int hauteur = x / largeurMax;
		for (int j = hauteur - 1; j <= hauteur + 1; j++) {
			for (int i = largeur - 1; i <= largeur + 1; i++) {
				Coordonnee cTmp = new Coordonnee(j, i, hauteurMax, largeurMax);
				if (i != largeur || j != hauteur) {
					if (Rules.giveLife()) {
						if (cTmp.isValid())
							if (mapTps1.get(cTmp) != null) {
								nbVoisin++;
							}
					}
					if (cTmp.isValid()) {
						if (mapTps1.get(cTmp) != null) {
							nbCelluleVoisine++;
						}
					}
				}
					
				
			}
		}
		if(mapTps1.get(coord) != null){
			Cellule c = mapTps1.get(coord); 
		if (nbCelluleVoisine == 2 || nbCelluleVoisine == 3) {
			if (Rules.haveLife()) {
				c.life--;
				if (c.life > 0)
					ajouteCellule(mapTps2, c);
			} else
				ajouteCellule(mapTps2, c);
		} else if (c.life > 0 && Rules.haveLife()) {
			c.life--;
			ajouteCellule(mapTps2, c);
		}}
		else {
			mapDonneVie.put(coord, new Integer(nbVoisin));
		}
	}

}
